#include "memalloc.hpp"


ReleasedList::ReleasedList(){
	head = new Node<uint64_t>(0);
	tail = new Node<uint64_t>(-1);
	head->next = tail;
}


//return is in pages after mem. it also drops page(s) into swap (from "released" state)
size_t ReleasedList::Pop(int num){

	while (true){
            Node<uint64_t> *node = head->next;
		if (node == tail){
			return -1;
		}
		uint64_t page = node->value;
		head->next = node->next;

                size_t ptr = MemAllocImpl::inst->count_page_swap[page].mem_page;
                delete node;
		if (!MemAllocImpl::inst->count_page_swap[page].get_count){
#ifdef WINDOWS
                            if (MemAllocImpl::inst->count_page_swap[page].mem_page != -1){
				fseek(MemAllocImpl::inst->pFile, page * MemAllocImpl::PAGESIZE, SEEK_SET);
				fwrite(MemAllocImpl::inst->mem + ptr * MemAllocImpl::PAGESIZE, 1, MemAllocImpl::PAGESIZE << num, MemAllocImpl::inst->pFile);
                            }
#endif

#ifdef LINUX			
                                if (MemAllocImpl::inst->count_page_swap[page].mem_page != -1)
                                    if (munmap(MemAllocImpl::inst->mem + ptr * MemAllocImpl::PAGESIZE, MemAllocImpl::PAGESIZE << num)){
                                        throw; //!!!throw some error!!!
                                    }
#endif
				MemAllocImpl::inst->count_page_swap[page].mem_page = -1;
				return ptr;
		}
	}

	
}


void ReleasedList::Push(uint64_t page){
        Node<uint64_t> *node = new Node<uint64_t>(page);
	node->next = head->next;
	head->next = node;
	return;
}
